// 92. 反转链表
// https://leetcode.cn/problems/reverse-linked-list-ii/description/
// 链表

/**
输入：head = [1,2,3,4,5], left = 2, right = 4
输出：[1,4,3,2,5]
示例 2：

输入：head = [5], left = 1, right = 1
输出：[5]
 */

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} left
 * @param {number} right
 * @return {ListNode}
 */
var reverseBetween = function (head, left, right) {
    if (!head) return head;
    if (!head.next) return head;

    let level = 1;
    let leftNode = null;
    let rightNode = null;

    let cur = head;
    let newLinks = null;
    while (cur) {
        if (level === left - 1) {
            leftNode = cur;
        }

        if (level === right + 1) {
            rightNode = cur;
            break;
        }

        cur = cur.next;
        level++;
    }

    newLinks = reverseList(leftNode ? leftNode.next : head, left, right);

    if (leftNode) {
        leftNode.next = newLinks.newHead;
    } else {
        head = newLinks.newHead;
    }

    if (rightNode) newLinks.tail.next = rightNode;

    return head;
};

var reverseList = function (head, curLevel, limitLevel) {
    let prev = null;
    let cur = head;
    let tail = head;

    while (cur) {
        next = cur.next;
        cur.next = prev;
        prev = cur;

        if (curLevel === limitLevel) {
            break;
        }

        curLevel++;
        cur = next;
    }

    return { newHead: prev, tail };
};

function listNodes(arr) {
    console.log(`[listNode] arr is ${JSON.stringify(arr)}`);
    if (!arr || arr.length < 1) {
        return null;
    }

    let ret = {
        val: null,
        next: null,
    };
    let temp = ret;
    for (let i = 0; i < arr.length; i++) {
        temp.val = arr[i];
        temp.next = null;
        if (i < arr.length - 1) {
            temp.next = {
                val: null,
                next: null,
            };
        }

        temp = temp.next;
    }
    // console.log(`[listNode complete] ret is ${JSON.stringify(ret)}`);
    return ret;
}

function flat(listNode) {
    if (listNode == null) {
        console.log(`flat: node is ${JSON.stringify([])}`);
        return [];
    }

    let arr = [];
    let node = listNode;
    // console.log(`flat: node is ${JSON.stringify(node)}`);
    do {
        arr.push(node.val);
        node = node.next;
    } while (!!node && !!node.next);
    if (!!node) {
        arr.push(node.val);
    }

    console.log(`flat complete: arr is ${JSON.stringify(arr)}`);
    return arr;
}

flat(reverseBetween(listNodes([1, 2, 3, 4, 5]), 2, 4)); // [1,4,3,2,5]
flat(reverseBetween(listNodes([5]), 1, 1)); // [5]
flat(reverseBetween(listNodes([3, 5]), 1, 1)); // [3,5];
flat(reverseBetween(listNodes([3, 5]), 1, 2)); // [3,5];
